"""
    Author:
    Date: 2018-11-26

    辅助函数。
"""

import hashlib
import time

from functools import wraps

from django.conf import settings
from django.shortcuts import render
from django.shortcuts import redirect

from entities import gm_mgr
from entities import user_mgr

# GMA手机登录的存根(openid目前对应手机号, 是用户的唯一ID)
SESSION_KEY_FOR_GMA_LOGIN = '_gma_openid'


def login(request, mobile):
    """ 登录 """
    request.session[SESSION_KEY_FOR_GMA_LOGIN] = mobile


def logout(request):
    """ 登出 """
    del request.session[SESSION_KEY_FOR_GMA_LOGIN]


def gma_login_required(view_func):
    """ 检测用户是否登录微信账号 """
    @wraps(view_func)
    def new_view_func(request, *args, **kwargs):
        mobile = request.session.get(SESSION_KEY_FOR_GMA_LOGIN, None)
        if mobile is None:
            return redirect('gma:login')

        # Return the HttpResponse object
        response = view_func(request, *args, **kwargs)
        return response

    return new_view_func


def get_request_openid(request):
    """ 获取request对应的openid """
    openid = request.session.get(SESSION_KEY_FOR_GMA_LOGIN, None)
    return openid


def get_request_gm(request):
    """ 获取request对应的user """
    openid = get_request_openid(request)
    return gm_mgr.get_gm_detail_by_openid(openid)


def get_request_gm_name(request):
    """ 获取request对应的user """
    openid = get_request_openid(request)
    gm = gm_mgr.get_gm_detail_by_openid(openid)
    if gm is None:
        return 'GM'
    return gm['nickname'] if gm['nickname'] else 'GM'


def get_request_gm_id(request):
    """ 获取request对应的user """
    openid = get_request_openid(request)
    gm = gm_mgr.get_gm_detail_by_openid(openid)
    return gm['id'] if gm else 0


def get_request_gm_apps(request):
    """ 获取request对应的user """
    gm_id = get_request_gm_id(request)
    apps = gm_mgr.get_gm_apps(gm_id)
    return apps


def build_app_filter_condition_for_request(request, bundle_id='u.origin_bundle_id'):
    """ 为request构造app过滤条件 """
    return f' {bundle_id}!="" '

    # 为官方GM账号开放所有的产品
    if is_official_gm(request):
        return f' {bundle_id}!="" '

    apps = []
    if request is not None:
        apps = get_request_gm_apps(request)

    if apps:
        apps = ','.join([f'"{x}"' for x in apps])
    else:
        apps = "'non.exist.app'"

    apps_condition = f' {bundle_id} in ({apps}) '
    return apps_condition


def build_guild_filter_condition_for_request(request):
    """ 为request构造app过滤条件 """
    # 为官方GM账号开放所有的产品
    if is_official_gm(request):
        return f' g.id>0 '

    gm_id = get_request_gm_id(request)
    guilds = gm_mgr.get_gm_guilds(gm_id)
    guilds_str = ','.join([str(x) for x in guilds])
    return f' g.id in ({guilds_str})'


def is_official_gm(request):
    """ 判断是否是官方GM账号 """
    gm_id = get_request_gm_id(request)
    return gm_id in settings.OFFICIAL_GM_IDS


def can_access_user(request, uid):
    """
    判断request是否可以访问指定用户的信息

    :param request:
    :param uid:
    :return:
    """
    # 判断用户是否存在
    user = user_mgr.get_user_detail(uid)
    if user is None:
        # 用户不存在
        return False

    # 官方GM可以访问所有的账号
    if is_official_gm(request):
        return True

    # 判断是否有权限
    gm_apps = get_request_gm_apps(request)
    if user['bundle_id'] not in gm_apps:
        return False

    return True


def can_access_guild(request, guild_id):
    """ 判断是否可以访问指定的公会 """
    guild_id = int(guild_id)

    gm_id = get_request_gm_id(request)
    if not gm_id:
        return False

    if not has_permission(request, gm_mgr.PERMISSION_GUILD_MANAGEMENT):
        return False

    # 官方GM可以访问所有的公会
    if is_official_gm(request):
        return True

    guilds = gm_mgr.get_gm_guilds(gm_id)
    return guild_id in guilds


def build_context(request):
    """ 构造上下文信息 """
    if not request:
        return {}

    user = get_request_gm(request)
    permissions = gm_mgr.get_gm_permission_detail(user['permission']) if user is not None else {}

    context = {
        'user': user,
        'permissions': permissions,
    }

    if settings.ENV_NAME.upper() == 'PROD':
        env = {
            'name': '(生产环境)',
            'favicon': 'favicon.png',
            'bg': 'hb-bg-prod',
        }
    elif settings.ENV_NAME.upper() == 'TEST':
        env = {
            'name': '(测试环境)',
            'favicon': 'favicon-t.png',
            'bg': 'hb-bg-test'
        }
    elif settings.ENV_NAME.upper() == 'DEV':
        env = {
            'name': '(开发环境)',
            'favicon': 'favicon-d.png',
            'bg': 'hb-bg-dev'
        }
    else:
        env = {
            'name': '(未配置!!)',
            'bg': 'hb-bg-dev'
        }
    context['env'] = env

    return context


def show_page_500(request, data):
    """ 显示500页面 """
    if type(data) == dict:
        message_id = data['id']
        message = data['message']
        message = f'[{message_id}] {message}'
    else:
        message = data
    return render(request, 'gma/500.html', {'message': message})


def show_page_tips(request, data):
    """ 显示提示页面 """
    if type(data) == dict:
        message_id = data['id']
        message = data['message']
        message = f'[{message_id}] {message}'
    else:
        message = data
    return render(request, 'gma/tips.html', {'message': message})


def show_success_page(request, message, redirect_url=''):
    """ 显示成功页面 """
    context = {
        'message': message,
        'redirect_url': redirect_url,
    }
    return render(request, 'gma/success.html', context)


def show_warn_page(request, message, redirect_url=''):
    """ 显示警告页面 """
    context = {
        'message': message,
        'redirect_url': redirect_url,
    }
    return render(request, 'gma/warn.html', context)


def sign_params(params):
    """ 对参数签名 """
    # 方便测试，自动增加timestamp字段
    if 'timestamp' not in params:
        params['timestamp'] = int(time.time())
    # 方便测试，自动增加nonce字段
    if 'nonce' not in params:
        params['nonce'] = 'nonce'

    temp = '&'.join(['%s=%s' % (key.lower(), params[key]) for key in sorted(params)])
    temp = temp + '&key=%s' % settings.GMA_KEY
    signature = hashlib.md5(temp.encode('utf-8')).hexdigest()
    return signature


class ApiParamsChecker(object):
    """ 对外调用的API接口的参数检测器 """

    def __init__(self, data, fields):
        self.params = {}
        for field in fields:
            self.params[field] = data.get(field, '')
        self.params['timestamp'] = data.get('timestamp', '')
        self.params['nonce'] = data.get('nonce', '')
        self.signature = data.get('signature', '')
        self.my_signature = sign_params(self.params)

    def is_valid_signature(self):
        """ 检测参数签名是否合法 """
        return self.signature.lower() == self.my_signature.lower()

    def get(self, param_name):
        """ 获取指定的参数 """
        return self.params.get(param_name, '')


def has_permission(request, permission_id):
    """ 判断是否有指定的权限 """
    openid = get_request_openid(request)
    return gm_mgr.has_permission_for_openid(openid, permission_id)


# ------------------------------------------------------------------------------
if __name__ == '__main__':
    print('ok')
